#include "Serial.h"

//Test 11 


Serial::Serial(bool* bitArray, int bitArraySize) : NistTest(bitArray, bitArraySize)
{
	this->testName = "Serial Test";
}


Serial::~Serial()
{
}


void Serial::start() {
	//Block length
	int m = (int)log(n) - 3; //TODO: Eingbae? Vorgabe ist : < log(n)-2; Muss mind. 3 sein, also n > 36
	if (m < 3) m = 3;
	bool *newBitArray;

	//first m-1 entries are copied to the end of the array
	if (m > 1) {
		newBitArray = new bool[n + m - 1];
		memcpy(newBitArray, bitArray, n ); 

		for (int i = 0; i < m-1; i++) {
			newBitArray[n + i] = bitArray[i];
		}
		bitArraySize = n+ m - 1;
	}
	else newBitArray = bitArray;

	// Overlapping tests for m, m-1, m-2 bit blocks
	int *freqs = new int[3]; //Sum of the squares(!) of hits
	int tmpHits = 0; 
	for (int mTest = m; mTest > m - 3; mTest--) {

		for (int i = 0; i < n - mTest; i++) { //run trough the bitArray
			for (int v = 0; v < pow(2, mTest); v++) { //run trough all possible values v for mTest bits
				for (int j = 0; j < mTest; j++) {//Compare all the bits
					if (bitCompare(newBitArray[i+j], j, v)) tmpHits++;
				}	
				freqs[m - mTest] += pow(tmpHits, 2);
			}
			tmpHits = 0;
		}
	}
	

	//compute Chi Sqauareds
	double chiSquared1 = ((pow(2, m) / n)  *  freqs[0]) - n;      // Chi Squared (m)
	double chiSquared2 = ((pow(2, m - 1) / n)  *  freqs[1]) - n;  // Chi Squared (m-1)
	double chiSquared3 = ((pow(2, m - 2) / n)  *  freqs[2]) - n;  // Chi Squared (m-2)

	//Compute Deltas
	double deltaChiSquaredM = chiSquared1 - chiSquared2;
	double deltaSquaredChiSquaredM = chiSquared1 - 2*chiSquared2 + chiSquared3;

	//PValue results
	addResult(boost::math::gamma_q(pow(2, m - 2), deltaChiSquaredM));
	addResult(boost::math::gamma_q(pow(2, m - 3), deltaSquaredChiSquaredM));
}

bool Serial::bitCompare(bool bit, int bitPos, int intValue) {
	int mask = 1;
	intValue >>= bitPos;
	return ((int)bit == (intValue & mask));
}